package cn.tedu.ivos.audit.service.impl;

import cn.tedu.ivos.application.mapper.ApplicationMapper;
import cn.tedu.ivos.application.pojo.entity.Application;
import cn.tedu.ivos.audit.mapper.AuditMapper;
import cn.tedu.ivos.audit.pojo.dto.AuditQuery;
import cn.tedu.ivos.audit.pojo.dto.AuditSaveParam;
import cn.tedu.ivos.audit.pojo.entity.Audit;
import cn.tedu.ivos.audit.pojo.vo.AuditVO;
import cn.tedu.ivos.audit.service.AuditService;
import cn.tedu.ivos.base.enums.ApplicationStatusEnum;
import cn.tedu.ivos.base.enums.AuditStatusEnum;
import cn.tedu.ivos.user.mapper.UserMapper;
import cn.tedu.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;

@Slf4j
@Service
@Transactional
public class AuditServiceImpl implements AuditService {
    @Autowired
    AuditMapper auditMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    ApplicationMapper applicationMapper;
    @Override
    public void insertAudit(Application application) {
        log.debug("为申请单创建对应审批单业务，参数：{}",application);
        //1.获取参数申请单中的审批人id集合[106,103]
        List<Long> userIdList=application.getAuditUserIdList();
        //2.遍历上方的审批人id集合，有几个id就生成一个对应的审批单
        for (int i=0;i<userIdList.size();i++){
            Audit audit=new Audit();
            //3.设置审批单相关的入库数据
            //3.1设置申请单id
            audit.setApplicationId(application.getId());
            //3.2设置审批人id
            audit.setAuditUserId(userIdList.get(i));
            //3.3设置审批单次序
            audit.setAuditSort(i);
            //3.4设置审批单状态
            if (i==0){
                //第一个审批单的审批状态为“待我审核 10”
                audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
            }else {
                //剩下后面的审批人的审批状态都为“待他人审核 20”
                audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
            }
            //3.5设置新增时间
            audit.setCreateTime(new Date());
            //4.审批单数据入库
            auditMapper.insert(audit);
        }
    }

    @Override
    public List<AuditVO> selectAuditByApplication(Long id) {
         log.debug("根据申请单id查询审批单业务，参数：{}", id);
        return auditMapper.selectAuditByApplicationId(id);
    }

    @Override
    public List<AuditVO> selectAudit(AuditQuery auditQuery) {
         log.debug("查询审批单业务，参数：{}", auditQuery);
        List<AuditVO> list = auditMapper.selectAudit(auditQuery);
        //遍历取出每一个审批单VO，依次为审批单VO中的审批人数据赋值
        for (int i=0;i<list.size();i++){
            AuditVO auditVO=list.get(i);
            assignAuditUserList(auditVO);
        }
        return list;
    }

    @Override
    public void updateAudit(AuditSaveParam auditSaveParam) {
        log.debug("审批处理业务，参数：{}",auditSaveParam);
        Audit audit=new Audit();
        BeanUtils.copyProperties(auditSaveParam,audit);
        audit.setUpdateTime(new Date());
        //更新当前的这条审批单，审批状态30或40是从前端传过来的
        auditMapper.update(audit);

        //准备更新当前审批单对应的申请单
        Application application=new Application();
        application.setId(audit.getApplicationId());
        application.setUpdateTime(new Date());
        //判断后续是做通过处理还是驳回处理
        if (audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())){
            //做通过处理
            //1.继续查当前审批单对应的其他审批单：（与当前审批单同一个申请单）
            AuditQuery auditQuery=new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //2.根据申请单id，查出批此申请单的所有未审批审批单总数
            Integer count=auditMapper.selectRestAuditCount(auditQuery);
            if (count>0){
                //还有未审批的审批单，刚刚更新的审批单不是最后一个
                //3.下一条审批单的次序是刚刚更新的那条审批单次序+1
                auditQuery.setAuditSort(audit.getAuditSort()+1);
                //4.根据批同一个申请单id与次序+1将下一条审批单查出来
                List<AuditVO>auditVOList=auditMapper.selectAudit(auditQuery);
                if (auditVOList!=null&&auditVOList.size()>0){
                    AuditVO auditVO=auditVOList.get(0);
                    //5.更新第二个审批单数据
                    Audit audit2=new Audit();
                    audit2.setId(auditVO.getId());
                    audit2.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
                    audit2.setUpdateTime(new Date());
                    auditMapper.update(audit2);
                }
                //设置申请单的状态为"审核中"
                application.setStatus(ApplicationStatusEnum.AUDIT.getCode());
                applicationMapper.update(application);
            }else {
                //没有未审批的审批单了，刚刚更新的审批单是最后一个
                application.setStatus(AuditStatusEnum.AUDITED.getCode());
                applicationMapper.update(application);
            }
        }else if (audit.getAuditStatus().equals(AuditStatusEnum.REJECT.getCode())){
            //做驳回处理
            AuditQuery auditQuery=new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //根据申请单id查询出所有的审批单
            List<AuditVO> auditVOList=auditMapper.selectAudit(auditQuery);
            //判断是否查出来数据
            if (auditVOList!=null&&auditVOList.size()>0){
                //遍历刚刚查出来的每一个审批单
                for (int i=0;i<auditVOList.size();i++){
                    AuditVO auditVO=auditVOList.get(i);
                    if (auditVO.getAuditStatus().equals(AuditStatusEnum.PENDING.getCode())){
                        auditMapper.deleteById(auditVO.getId());
                    }
                }
            }
            //设置申请单的状态为“已驳回”
            application.setStatus(ApplicationStatusEnum.REJECT.getCode());
            application.setRejectReason(auditSaveParam.getRejectReason());
            applicationMapper.update(application);
        }
    }

    @Override
    public List<AuditVO> selectAuditByApplicationId(Long id) {
        log.debug("根据申请单id查询审批单业务，参数：{}", id);
        return auditMapper.selectAuditByApplicationId(id);
    }

    private void assignAuditUserList(AuditVO auditVO) {
        //1.准备用来装多个审批人姓名的空集合
        List<String> auditUsernameList = new ArrayList<>();
        //2.准备用来装多个审批人id的空集合
        List<Long> auditUserIdList = new ArrayList<>();
        //3.根据审批VO中的申请单id,查出此申请单对应的所有审批对象
        List<AuditVO> auditVOList =
                auditMapper.selectAuditByApplicationId(auditVO.getApplicationId());
        //4.遍历审批单VO集合,依次取出每个审批单VO
        for (int i = 0; i < auditVOList.size(); i++) {
            //5.获取当前遍历到的审批单VO中的审批人id
            Long userId = auditVOList.get(i).getAuditUserId();
            //6.将审批人id装入上方的id空集合中
            auditUserIdList.add(userId);
            //7.根据刚刚取出来的审批人id查出此人姓名，并装入上方审批人姓名空集合中
            UserVO userVO = userMapper.selectById(userId);
            auditUsernameList.add(userVO.getUsername());
        }
        //8.准备一个拼接工具，帮我们将多个审批人姓名连成一个字符串
        StringJoiner stringJoiner = new StringJoiner(",");
        //9.将拼接好的审批人姓名字符串赋值给方法形参AuditVO
        for(String username : auditUsernameList){
            stringJoiner.add(username);
        }
        auditVO.setAuditUsernameList(stringJoiner.toString());
        //10.将准备好的审批人id集合赋值给方法形参AuditVO
        auditVO.setAuditUserIdList(auditUserIdList);
    }
}
